import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { StudySession, CheckIn, StudyStats } from '@/types';
import { Platform } from 'react-native';

interface StudyState {
  sessions: StudySession[];
  checkIns: CheckIn[];
  currentSession: StudySession | null;
  isLoading: boolean;
  error: string | null;
  
  // Session management
  startSession: (userId: string) => void;
  endSession: (contentIds: string[]) => void;
  
  // Check-in management
  checkIn: (userId: string, date?: string) => void;
  makeupCheckIn: (userId: string, date: string) => void;
  
  // Stats
  getStats: (userId: string) => StudyStats;
}

// Helper to get today's date in ISO format (YYYY-MM-DD)
const getTodayDate = () => {
  const date = new Date();
  return date.toISOString().split('T')[0];
};

// Helper to generate mock weekly data
const generateMockWeeklyData = () => {
  const data = [];
  const today = new Date();
  
  for (let i = 6; i >= 0; i--) {
    const date = new Date();
    date.setDate(today.getDate() - i);
    const dateStr = date.toISOString().split('T')[0];
    data.push({
      date: dateStr,
      minutes: Math.floor(Math.random() * 60) + 10, // Random between 10-70 minutes
    });
  }
  
  return data;
};

// Create a fallback storage for web environments where AsyncStorage might not be available
const createNoopStorage = () => {
  return {
    getItem: (_name: string) => Promise.resolve(null),
    setItem: (_name: string, _value: string) => Promise.resolve(),
    removeItem: (_name: string) => Promise.resolve(),
  };
};

// Use AsyncStorage when available, otherwise use a noop storage
const storage = Platform.OS === 'web' 
  ? createNoopStorage()
  : AsyncStorage;

export const useStudyStore = create<StudyState>()(
  persist(
    (set, get) => ({
      sessions: [],
      checkIns: [],
      currentSession: null,
      isLoading: false,
      error: null,
      
      startSession: (userId: string) => {
        const newSession: StudySession = {
          id: Math.random().toString(36).substring(2, 9),
          userId,
          date: new Date().toISOString(),
          duration: 0,
          contentIds: [],
        };
        
        set({ currentSession: newSession });
      },
      
      endSession: (contentIds: string[]) => {
        const { currentSession, sessions } = get();
        
        if (!currentSession) {
          set({ error: 'No active session to end' });
          return;
        }
        
        // Calculate duration in minutes
        const startTime = new Date(currentSession.date).getTime();
        const endTime = new Date().getTime();
        const durationMinutes = Math.round((endTime - startTime) / (1000 * 60));
        
        const completedSession: StudySession = {
          ...currentSession,
          duration: durationMinutes,
          contentIds,
        };
        
        set({
          sessions: [...sessions, completedSession],
          currentSession: null,
        });
      },
      
      checkIn: (userId: string, date = getTodayDate()) => {
        const { checkIns } = get();
        
        // Check if already checked in for this date
        const alreadyCheckedIn = checkIns.some(
          checkIn => checkIn.date === date && checkIn.userId === userId
        );
        
        if (alreadyCheckedIn) {
          set({ error: 'Already checked in for this date' });
          return;
        }
        
        const newCheckIn: CheckIn = {
          date,
          userId,
        };
        
        set({ checkIns: [...checkIns, newCheckIn] });
      },
      
      makeupCheckIn: (userId: string, date: string) => {
        const { checkIns } = get();
        
        // Check if already checked in for this date
        const alreadyCheckedIn = checkIns.some(
          checkIn => checkIn.date === date && checkIn.userId === userId
        );
        
        if (alreadyCheckedIn) {
          set({ error: 'Already checked in for this date' });
          return;
        }
        
        const newCheckIn: CheckIn = {
          date,
          userId,
          isMakeup: true,
        };
        
        set({ checkIns: [...checkIns, newCheckIn] });
      },
      
      getStats: (userId: string) => {
        const { sessions } = get();
        const userSessions = sessions.filter(session => session.userId === userId);
        
        // Calculate total study time
        const totalTime = userSessions.reduce((total, session) => total + session.duration, 0);
        
        // Calculate daily average
        const dailyAverage = userSessions.length > 0 
          ? Math.round(totalTime / userSessions.length) 
          : 0;
        
        // For demo purposes, generate mock data for charts
        const weeklyData = generateMockWeeklyData();
        
        const contentTypeDistribution = [
          { type: 'Words', minutes: Math.floor(totalTime * 0.3) },
          { type: 'Phrases', minutes: Math.floor(totalTime * 0.2) },
          { type: 'Sentences', minutes: Math.floor(totalTime * 0.25) },
          { type: 'Stories', minutes: Math.floor(totalTime * 0.25) },
        ];
        
        const difficultyDistribution = [
          { level: 'Beginner', minutes: Math.floor(totalTime * 0.5) },
          { level: 'Intermediate', minutes: Math.floor(totalTime * 0.3) },
          { level: 'Advanced', minutes: Math.floor(totalTime * 0.2) },
        ];
        
        return {
          totalTime,
          dailyAverage,
          weeklyData,
          contentTypeDistribution,
          difficultyDistribution,
        };
      },
    }),
    {
      name: 'study-storage',
      storage: createJSONStorage(() => storage),
    }
  )
);